package com.gitee.wsl.concurrent.service

import com.gitee.wsl.concurrent.scheduler.Scheduler
import com.gitee.wsl.concurrent.scheduler.ext.asCoroutineDispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Runnable
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration

interface ScheduledExecutorService {

    val isTerminated: Boolean

    val isShutdown: Boolean

    fun shutdown()

    fun scheduleAtFixedRate(initialDelay: Long,
                            periodInMilliSeconds: Long,
                            milliseconds: DurationUnit,
                            runnable: Runnable,
    ) {
        val delay = initialDelay.toDuration(milliseconds)
        val period = periodInMilliSeconds.toDuration(milliseconds)
        scheduleAtFixedRate(delay,period,runnable)
    }

    fun scheduleAtFixedRate(
        delay: Duration = Duration.ZERO,
        period: Duration = Duration.INFINITE,
        runnable: Runnable,
    )

    fun asCoroutineDispatcher(): CoroutineDispatcher

    fun submit(wrapped: Runnable): ScheduledFuture<*> {
        TODO()
    }

    fun shutdownNow()  = shutdown()
    fun awaitTermination(time: Duration) {}

    fun scheduleAt(delay: Duration, wrapped: Runnable) : ScheduledFuture<*> {
        TODO()
    }

    fun scheduleAtFixedRateFuture(
        delay: Duration = Duration.ZERO,
        period: Duration = Duration.INFINITE,
        runnable: Runnable,
    ): ScheduledFuture<*>{
        TODO()
    }
}

fun ScheduledExecutorService(schedule: Scheduler):ScheduledExecutorService = DefaultScheduledExecutorService(schedule)

class DefaultScheduledExecutorService(
    val schedule: Scheduler
) : ScheduledExecutorService{

    val schedulerExecutor = schedule.newExecutor()

    override var isTerminated: Boolean = false

    override val isShutdown: Boolean
        get() = schedulerExecutor.isDisposed

    override fun asCoroutineDispatcher(): CoroutineDispatcher {
       return schedule.asCoroutineDispatcher()
    }

    override fun shutdown() {
        schedule.destroy()
    }

    override fun scheduleAtFixedRate(delay: Duration, period: Duration, runnable: Runnable) {
        schedulerExecutor.submit(delay,period,runnable)
    }

}